package skinfactory
{
	import events.ImageLoaderEvent;
	import events.SkinFactoryEvent;
	import events.XMLLoaderEvent;
	
	import external.ImageLoader;
	import external.XMLLoader;
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.geom.Matrix;
	import flash.geom.Rectangle;
	
	public class SkinFactory extends Sprite
	{
		private static var _skinFactory:SkinFactory = null;
		public 	static function getInstance():SkinFactory 
		{
			if(_skinFactory == null) 
			{		
				trace("■ SKIN DATA LOAD PROCESS ▧▧▧▧▧▧▧▧▧▧▧▧");		 
				_skinFactory = new SkinFactory( new SingletonEnforcer() );
			}
			return _skinFactory;
		}
		public function SkinFactory(enforcer:SingletonEnforcer)
		{
			
		}
		private var xmlData: XML;
		private var xmlLoader: XMLLoader;
		
		private var imgData: Bitmap;
		private var skinLoader: ImageLoader;
		
		private var blnXMLLoadComplete: Boolean = false;
		private var blnIMGLoadComplete: Boolean = false;
		
		// XML File Load
		public function loadSkinXMLData( path: String ): void
		{
			xmlLoader = new XMLLoader();
			xmlLoader.url = path;
			xmlLoader.load();
			xmlLoader.addEventListener( XMLLoaderEvent.COMPLETE, onSkinXMLDataLoadComplete );
			xmlLoader.addEventListener( XMLLoaderEvent.FAIL, onSkinXMLLoadFail );
		}
		public function setXMLData( data: XML ): void
		{
			xmlData = data;
			blnXMLLoadComplete = true;
			this.skinDataLoadComplete();
		}
		private function onSkinXMLDataLoadComplete( e: XMLLoaderEvent ): void
		{
			trace( "\t- SkinData Load Complete " );
			xmlData = xmlLoader.xml;
			blnXMLLoadComplete = true;
			this.skinDataLoadComplete();
		}
		private function onSkinXMLLoadFail( e: XMLLoaderEvent ): void
		{
			trace( "\t- SkinData Load Fail " + xmlLoader.url );
		}
		
		// Image File Load
		public function loadSkinImageData( path: String ): void
		{
			skinLoader = new ImageLoader();
			skinLoader.url = path;
			skinLoader.load();
			skinLoader.addEventListener( ImageLoaderEvent.COMPLETE, onSkinImgDataLoadComplete );
			skinLoader.addEventListener( ImageLoaderEvent.FAIL, onImageLoadFail );
		}
		private function onSkinImgDataLoadComplete( e: ImageLoaderEvent ): void
		{
			trace( "\t- SkinImage Load Complete" );
			imgData = new Bitmap( skinLoader.bitmapData )
			blnIMGLoadComplete = true;
			this.skinDataLoadComplete();
		}
		private function onImageLoadFail( e: ImageLoaderEvent ): void
		{
			trace( "SkinImage Load Fail : " + e.data );
		}
		private function skinDataLoadComplete(): void
		{
			if( blnIMGLoadComplete == true && blnXMLLoadComplete == true )
			{
				this.dispatchEvent( new SkinFactoryEvent( SkinFactoryEvent.LOAD_COMPLETE ) );
			}
		}
		
		private function getSkinXml( tag:String):XML 
		{
			
			var imgXml:XML;		
			for(var i:int=0; i < xmlData.child("image").children().length(); ++i) {
				var name:String = xmlData.child("image").children()[i].name().localName;
				if(name == tag) {
					imgXml = xmlData.child("image").children()[i];
					break;
				}
			}
			return imgXml;			
		}
		public function getSkinBitmap( tag:String):Bitmap
		{ 
			//trace("imgXml=",imgXml.toXMLString());
			var imgXml:XML = getSkinXml(tag);
			
			var rect:Array = imgXml.@rect.split(",");
			//var sliceInterval:String = imgXml.@sliceTurm;
			//var grid:String = imgXml.@grid;
			
			if(rect == null || rect.length < 4) return null;
						
			return new Bitmap(getBitmapData(rect));
		}
		private  function getBitmapData(rect:Array):BitmapData
		{
			var bitmapData:BitmapData = new BitmapData(rect[2],rect[3],true, 0x00000000);
			var mat: Matrix = new Matrix();
			mat.tx = -rect[0];
			mat.ty = -rect[1];
			bitmapData.draw(imgData,mat,null,null,null,true);
									
			return bitmapData;			
		}
		public function getSkin9GridBitmap(imgTag:String):ScaleBitmap
		{
			var imgXml:XML = getSkinXml(imgTag);
			
			var rect:Array = imgXml.@rect.split(",");
			var grid:Array = imgXml.@grid.split(",");
			
			if(rect == null || rect.length < 4) return null;
			var bitmap:ScaleBitmap = new ScaleBitmap(getBitmapData(rect));
			if(grid == null || grid.length < 4) return bitmap;
						
			var gridRect:Rectangle = new Rectangle(grid[0],grid[1],grid[2],grid[3]);
			bitmap.scale9Grid = gridRect ;
			return bitmap;
		}	
		public function getSkinButton(imgTag:String): ImageButton
		{
			var imgXml:XML = getSkinXml(imgTag);
			var normalData:BitmapData;
			var overData:BitmapData;
			var downData:BitmapData;
						
			var rect:Array = imgXml.@rect.split(",");
		
			var sliceInterval:Number = Number(imgXml.@sliceTurm);
			
			if(rect == null || rect.length < 4) return null;
			var bitmap:Bitmap = new Bitmap(getBitmapData(rect));

			var height:uint = rect[3];
			var mat: Matrix = new Matrix();
			mat.tx = -rect[0];
			mat.ty = -rect[1];
			
			rect[3] = sliceInterval;			
			normalData = new BitmapData(rect[2],rect[3],true, 0x00000000);
			normalData.draw(imgData,mat,null,null,null,true);
			
			if(sliceInterval < height) {
				mat.ty -= sliceInterval;				
				overData = new BitmapData(rect[2],rect[3],true, 0x00000000);
				overData.draw(imgData,mat,null,null,null,true);
			
				if(2*sliceInterval <= height) {
					mat.ty -= sliceInterval;					
					downData = new BitmapData(rect[2],rect[3],true, 0x00000000);
					downData.draw(imgData,mat,null,null,null,true);
				}
			}
			//trace("overData == null : ",overData == null);
			//trace("downData == null : ",downData == null);
			var imgButton:ImageButton = new ImageButton(new Bitmap(normalData),new Bitmap(overData),new Bitmap(downData));
			return imgButton;
		}	
		public function getButtonImg(imgTag:String): Array
		{
			var imgXml:XML = getSkinXml(imgTag);
			var normalData:BitmapData;
			var overData:BitmapData;
			var downData:BitmapData;
						
			var rect:Array = imgXml.@rect.split(",");
			var sliceInterval:Number = Number(imgXml.@sliceTurm);
			if(rect == null || rect.length < 4) return null;
			var bitmap:Bitmap = new Bitmap(getBitmapData(rect));

			var height:uint = rect[3];
			var mat: Matrix = new Matrix();
			mat.tx = -rect[0];
			mat.ty = -rect[1];
			
			rect[3] = sliceInterval;			
			normalData = new BitmapData(rect[2],rect[3],true, 0x00000000);
			normalData.draw(imgData,mat,null,null,null,true);
			
			if(sliceInterval < height) {
				mat.ty -= sliceInterval;				
				overData = new BitmapData(rect[2],rect[3],true, 0x00000000);
				overData.draw(imgData,mat,null,null,null,true);
			
				if(2*sliceInterval <= height) {
					mat.ty -= sliceInterval;					
					downData = new BitmapData(rect[2],rect[3],true, 0x00000000);
					downData.draw(imgData,mat,null,null,null,true);
				}
			}
			//trace("overData == null : ",overData == null);
			//trace("downData == null : ",downData == null);
			var imgButton: Array = new Array();
			if( String( imgXml.@grid ).length != 0 )
			{
				var grid:Array = imgXml.@grid.split(",");
				if( grid == null || grid.length < 4 )
				{
					imgButton.push( new Bitmap(normalData) )
					imgButton.push( new Bitmap(overData) )
					imgButton.push( new Bitmap(downData) );
				}	
				else
				{
					var scaleBitmap:ScaleBitmap = new ScaleBitmap( normalData );
					var gridRect:Rectangle = new Rectangle(grid[0],grid[1],grid[2],grid[3]);
					scaleBitmap.scale9Grid = gridRect ;
					imgButton.push( scaleBitmap )
					
					scaleBitmap = new ScaleBitmap( overData );
					scaleBitmap.scale9Grid = gridRect;
					imgButton.push( scaleBitmap )
					
					scaleBitmap = new ScaleBitmap( downData );
					scaleBitmap.scale9Grid = gridRect;
					imgButton.push( scaleBitmap );
				}
			}
			else
			{
				imgButton.push( new Bitmap(normalData) )
					imgButton.push( new Bitmap(overData) )
					imgButton.push( new Bitmap(downData) );
			}
			
			
			return imgButton;
		}
	}
}
class SingletonEnforcer {}